import {getFormData} from '@/utils';
import {uploadImage, uploadVideoSlice, mergeVideo, uploadVideo, clearCache,uploadImages } from '@/api/news';
import {nanoid} from "nanoid";
import {showProgress} from '@/libs/progress'
import {ref} from 'vue'

// 获取视频封面图
const getPoster = (file) => new Promise(resolve => {
  const video = document.createElement('video')
  video.setAttribute('muted', 'muted')
  video.setAttribute('autoplay', 'autoplay')
  const videoSrc = URL.createObjectURL(file)
  video.setAttribute('src', videoSrc)
  video.currentTime = 3
  const container = document.createElement('div')
  container.classList.add('__jurong__video_container')
  video.onloadeddata = () => {
    container.appendChild(video)
    document.body.appendChild(container)
    const canvas = document.createElement('canvas'),
        w = video.clientWidth,
        h = video.clientHeight;
    canvas.width = w
    canvas.height = h
    canvas.getContext('2d').drawImage(video, 0, 0, w, h)
    container.appendChild(canvas)
    canvas.toBlob(bold => {
      const _file = new File([bold], 'poster.jpeg', {type: 'image/jpg'})
      URL.revokeObjectURL(videoSrc)
      container.remove()
      resolve(_file)
    })
  }
})

const concurrence = (target, maxNum, itemSuccess, isCancel) => {
  return new Promise(resolve => {
    if (!target.length) {
      resolve([])
      return
    }
    const result = []
    let index = 0,
        count = 0;
    const request = async () => {
      if (isCancel.value) {
        console.log('取消')
        resolve(result)
        return
      }
      if (index >= target.length) return
      const curIdx = index
      index++;
      const currentFile = target[curIdx]
      try {
        const res = await uploadVideoSlice(getFormData({
          video: currentFile,
        }))
        result[curIdx] = res
        itemSuccess(res)
      } catch (e) {
        if (e instanceof Error) {
          result[curIdx] = e.message
        } else {
          result[curIdx] = e.toString()
        }
      } finally {
        count++;
        if (count === target.length) {
          resolve(result)
        } else {
          await request()
        }
      }
    }
    const lim = Math.min(target.length, maxNum)
    for (let i = 0; i < lim; i++) {
      request()
    }
  })
}

// 切片上传  每个chunk默认为2MB
const upload = async (file, insertFn, chunkSize = 1024 * 1024 * 4) => {
  // const poster = await getPoster(file)
  const {size, name, type} = file
  // 判断 文件大小 小于4mb 直接上传
  if (size <= chunkSize) {
    await uploadFile(file, insertFn)
    return
  }
  const progress = ref(0)
  const isCancel = ref(false)
  // SUCCESS_LIST = [];
  showProgress(progress, async () => {
    isCancel.value = true
    const resp = await clearCache({
      topicId,
    })
    console.log(resp)
  })
  // 文件大小超过 4mb 进行切片上传
  const topicId = nanoid(6) + '_chunk_'
  const fileMap = sliceFile(file, size, chunkSize, topicId);
  let MAX = fileMap.size,
      cur = 0;
  const result = await concurrence([...fileMap.values()], 3, ({success: _success}) => {
    if (_success) {
      cur += 1;
      progress.value = Math.floor((cur / MAX) * 100);
    }
  }, isCancel)
  const success = result.length === MAX && result.every(item => item.success)
  if (success) {
    await merge([...fileMap.keys()], getFileName(name, type), insertFn)
  }
}
const merge = async (names, originalname, cb) => {
  const {success, src} = await mergeVideo({
    names,
    originalname,
  })
  if (success) {
    cb(src)
  }
}

const getFileName = (filename, fileType) => {
  const nameReg = /^[\s\S]+\.(mp4|m4v|avi|ogm|wmv|mpg|webm|ogv|mov|asx|mpeg)$/;
  const typeReg = /^[\s\S]+\/(mp4|m4v|avi|ogm|wmv|mpg|webm|ogv|mov|asx|mpeg)/;
  const typeExec = typeReg.exec(fileType)
  if (typeExec) {
    return `${nanoid(15)}.${typeExec[1]}`
  }
  const nameExec = nameReg.exec(filename);
  if (nameExec) {
    return `${nanoid(10)}.${nameExec[1]}`
  }
  throw new Error('文件的类型不确定!请转换视频的类型!')
}

// 把文件切片
const sliceFile = (file, maxSize, chunkSize, topicId) => {
  const {type} = file,
      fileMap = new Map();
  let currentSize = 0,
      idx = 0;
  while (currentSize < maxSize) {
    const chunk = file.slice(currentSize, currentSize + chunkSize)
    const fileName = `${topicId}${idx}`;
    const chunkFile = new File([chunk], fileName, {type});
    fileMap.set(fileName, chunkFile)
    currentSize += chunkSize
    idx++
  }
  return fileMap
}

// 单个上传
const uploadFile = async (file, insertFn) => {
  const formData = getFormData({
    video: file
  })
  const {success, src} = await uploadVideo(formData)
  if (success) {
    insertFn(src)
  }
}

export default (callback) => ({
  // 富文本上传图片功能
  uploadImage: {
    async customUpload(file, insertFn) {
      const checkReg = /^image\/([\s\S]+)$/
      const {type} = file
      const regRes = checkReg.exec(type)
      if (!regRes) {
        console.log('请选择图片!')
        return
      }
      const formData = getFormData({
        file,
      })
	  console.log(formData,'数据');
	  
      const {msg, data,code} = await uploadImages(formData)
      if (!code) {
        console.log('文件上传失败!')
        return
      }
      insertFn(data.fullurl, '', '')
    }
  },
  // 富文本上传视频功能
  uploadVideo: {
    async customUpload(file, insertFn) {
      await upload(file, insertFn)
    }
  },
  // 富文本插入图片回调
  insertImage: {
    onInsertedImage(imgNode) {
      if (!imgNode) return
      const {src} = imgNode
      callback(src)
    }
  },
  // 富文本插入视频回调
  insertVideo: {
    onInsertedVideo(videoNode) {
      if (videoNode) {
        const {src} = videoNode
        callback(src)
      }
    }
  },
  fontSize: {
    fontSizeList: [
      '12px',
      '16px',
      '18px',
      '19px',
      '20px',
      '25px',
      '30px',
      '40px',
      '50px',
    ]
  },
  // lineHeight: {
  //   lineHeightList: ['1', '1.5', '2', '2.5']
  // }
})
